Completed
Pull Request — master (#69)
by Marcelo
30s
created

input.js ➔ ... ➔ ???   A

Complexity

Conditions 2
Paths 3

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
c 1
b 0
f 0
nc 3
dl 0
loc 19
rs 9.4285
nop 3
1
import { resolve } from 'bluebird';
2
import {
3
    __,
4
    assoc,
5
    concat,
6
    curry,
7
    has,
8
    keys,
9
    map,
10
    merge,
11
    reduce,
12
    toPairs
13
} from 'ramda';
14
import { green, red, yellow } from 'colors/safe';
15
import { createPromptModule } from 'inquirer';
16
import DatePickerPrompt from 'inquirer-datepicker-prompt';
17
import ChalkPipe from 'inquirer-chalk-pipe';
18
import { validator, filter } from './types';
19
20
/**
21
 * Emits a warning to stdout
22
 *
23
 * @param {String} message
24
 * @return {Promise}
25
 */
26
export const emitWarning = concat(' ⚠ Warning: ') & yellow & console.log & resolve;
27
28
/**
29
 * Emits an error to stdout
30
 *
31
 * @param {String} message
32
 * @return {Promise}
33
 */
34
export const emitError = concat(' ✗ Error: ') & red & console.log & resolve;
35
36
/**
37
 * Emits a success message
38
 *
39
 * @param {String} message
40
 * @return {Promise}
41
 */
42
export const emitSuccess = concat(' ✔ Success: ') & green & console.log & resolve;
43
44
/**
45
 * Renames the keys of an object
46
 *
47
 * @sig {a: b} -> {a: *} -> {b: *}
48
 */
49
const renameKeys = curry((keysMap, obj) => reduce((acc, key) =>
50
    assoc(keysMap[key] || key, obj[key], acc), {}, keys(obj)));
51
52
const components = {
53
    Calendar: ~({
54
        type: 'datetime',
55
        format: ['m', '/', 'd', '/', 'yy'],
56
        filter: filter.Calendar,
57
        validate: validator.Calendar }),
58
    Char: ({ type }) => ({ filter: filter.Char(type.length) }),
59
    Checkbox: ~({ type: 'confirm' }),
60
    Color: ~({ type: 'chalk-pipe' }),
61
    DoubleRange: ({ type }) => ({
62
        filter: filter.Double,
63
        validate: validator.Range(type.from, type.to) }),
64
    DateTime: ~({ type: 'datetime' }),
65
    Double: ~({ validate: validator.Double, filter: filter.Double }),
66
    Email: ~({ validate: validator.Email }),
67
    Integer: ~({ validate: validator.Integer, filter: filter.Integer }),
68
    IntegerRange: ({ type }) => ({
69
        filter: filter.Integer,
70
        validate: validator.Range(type.from, type.to) }),
71
    IntegerMultiRange: ({ type }) => ({
72
        filter: filter.IntegerMultiRange,
73
        validate: validator.IntegerMultiRange(type.from, type.to) }),
74
    Natural: ~({ validate: validator.Natural, filter: filter.Integer }),
75
    OneOf: ({ type }) => ({ type: 'list', choices: type.values }),
76
    String: ~({ type: 'input' }),
77
    Url: ~({ validate: validator.Url }),
78
    Money: ~({ validate: validator.Money, filter: filter.Money })
79
};
80
81
/**
82
 * Converts a Rung CLI question object to an Inquirer question object
83
 *
84
 * @author Marcelo Haskell Camargo
85
 * @param {String} name
0 ignored issues
show
Documentation introduced by
The parameter name does not exist. Did you maybe forget to remove this comment?
Loading history...
86
 * @param {Object} config
0 ignored issues
show
Documentation introduced by
The parameter config does not exist. Did you maybe forget to remove this comment?
Loading history...
87
 * @return {Object}
88
 */
89
function toInquirerQuestion([name, config]) {
90
    const component = has(config.type.name, components)
91
        ? components[config.type.name]
92
        : components.String;
93
94
    return merge(config
95
        | renameKeys({ description: 'message' })
96
        | merge(__, { name }), component(config));
97
}
98
99
/**
100
 * Returns the pure JS values from received questions that will be answered
101
 *
102
 * @author Marcelo Haskell Camargo
103
 * @param {Object} questions
104
 * @return {Promise} answers for the questions by key
105
 */
106
export function ask(questions) {
107
    const prompt = createPromptModule();
108
    prompt.registerPrompt('datetime', DatePickerPrompt);
109
    prompt.registerPrompt('chalk-pipe', ChalkPipe);
110
    return resolve(prompt(questions | toPairs | map(toInquirerQuestion)));
111
}
112